/*
 * $Id: OpenedResultTransfer.java 23 2002-09-29 13:59:30Z bpruessmann $
 *
 * Copyright (c) 2001 Boris Pruessmann and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Common Public License v0.5
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors:
 *    Boris Pruessmann - Initial implementation.
 */
package net.sourceforge.p4eclipse.internal.ui.dnd;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import net.sourceforge.p4eclipse.core.Policy;
import net.sourceforge.p4eclipse.core.api.IOpenedResult;
import org.eclipse.swt.dnd.ByteArrayTransfer;
import org.eclipse.swt.dnd.TransferData;

/**
  * The <code>OpenedResultTransfer</code> class is used to transfer an array
  * of <code>IOpenedResult</code>s from one part to another in a drag and
  * drop operation.
  * 
  * @version 	$Revision: 23 $
  * @author		<a href="mailto:bpruessmann@users.sourceforge.net">Boris Pruessmann</a>
  */
public class OpenedResultTransfer extends ByteArrayTransfer
{
	/** Singleton instance. */
	private static final OpenedResultTransfer instance = new OpenedResultTransfer();

	// Create a unique ID to make sure that different Eclipse
	// applications use different "types" of <code>ResourceTransfer</code>
	private static final String TYPE_NAME = "resource-transfer-format:" + System.currentTimeMillis() + ":" + instance.hashCode();//$NON-NLS-2$//$NON-NLS-1$

	private static final int TYPE_ID = registerType(TYPE_NAME);

	/**
	  * Returns the singleton instance.
	  * @return the singleton instance.
	  */
	public static OpenedResultTransfer getInstance() 
	{
		return instance;
	}

	/** Creates a new transfer object. */
	private OpenedResultTransfer() { }
	
	/** @see Transfer#getTypeIds() */
	protected int[] getTypeIds() 
	{
		return new int[]{ TYPE_ID };
	}
	
	/** @see Transfer#getTypeNames() */
	protected String[] getTypeNames() 
	{
		return new String[]{ TYPE_NAME };
	}
	
	/** @see Transfer#javaToNative(java.lang.Object, org.eclipse.swt.dnd.TransferData) */
	protected void javaToNative (Object data, TransferData transferData)
	{
		if (!(data instanceof IOpenedResult[]))
			return;
			
		IOpenedResult[] openedResult = (IOpenedResult[])data;
	
		int openedResultCount = openedResult.length;
		try 
		{
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			DataOutputStream dataOut = new DataOutputStream(out);
	
			//write the number of resources
			dataOut.writeInt(openedResultCount);
	
			//write each resource
			for (int i = 0; i < openedResult.length; i++)
				writeOpenedResult(dataOut, openedResult[i]);
	
			//cleanup
			dataOut.close();
			out.close();
		
			super.javaToNative(out.toByteArray(), transferData);
		}
		catch (IOException e) 
		{
			//it's best to send nothing if there were problems
		}			
	}
	
	/** @see Transfer#nativeToJava(TransferData) */
	protected Object nativeToJava(TransferData transferData)
	{
		byte[] bytes = (byte[])super.nativeToJava(transferData);
		if (bytes == null)
			return null;
	
		DataInputStream in = new DataInputStream(new ByteArrayInputStream(bytes));
		try 
		{
			int count = in.readInt();
			
			IOpenedResult[] results = new IOpenedResult[count];
			for (int i = 0; i < count; i++) 
				results[i] = readOpenedResult(in);
			
			return results;
		} 
		catch (IOException e) 
		{
			return null;
		}
	}
		
	private void writeOpenedResult(DataOutputStream dataOut, IOpenedResult openedResult) 
		throws IOException 
	{
		dataOut.writeUTF(openedResult.getDepotFilename());
	}	

	private IOpenedResult readOpenedResult(DataInputStream dataIn) 
		throws IOException 
	{
		TransferOpenedResult result = new TransferOpenedResult ();
		result.depotFilename = dataIn.readUTF();
		
		return result;
	}	

	/**
	  * <code>IOpenedResult</code> implementation returned by readOpenedResult.
	  * Only contains information needed by drag and drop operation.
	  */
	private static class TransferOpenedResult implements IOpenedResult
	{
		private String depotFilename;
		
		/** @see IOpenedResult#getAction() */
		public String getAction() { Policy.assertTrue(false); return null; }

		/** @see IOpenedResult#getChangelist() */
		public Integer getChangelist() { Policy.assertTrue(false); return null; }

		/** @see IOpenedResult#getClientFilename() */
		public String getClientFilename() { Policy.assertTrue(false); return null; }

		/** @see IOpenedResult#getClientName() */
		public String getClientName() { Policy.assertTrue(false); return null; }

		/** @see IOpenedResult#getDepotFilename() */
		public String getDepotFilename() { return depotFilename; }

		/** @see IOpenedResult#getRevision() */
		public Integer getRevision() { Policy.assertTrue(false); return null; }

		/** @see IOpenedResult#getType() */
		public String getType() { Policy.assertTrue(false); return null; }

		/** @see IOpenedResult#getUserName() */
		public String getUserName() { Policy.assertTrue(false); return null; }

		/** @see IAdaptable#getAdapter(Class) */
		public Object getAdapter(Class adapter) { Policy.assertTrue(false); return null; }
	}
}
